#include "application.h"
#include "gui.h"

GUI * gui_new( ) {
	return (GUI *) malloc(sizeof(GUI));
}

void gui_free(Application *application) {
	gtk_main_quit( );
}

void gui_activate(GtkSwitch *widget, GParamSpec *param, Application *application) {
	if(gtk_switch_get_active(widget))
		application_turn_on(application);
	else application_turn_off(application);
}

void gui_connect_signals(Application *application) {
	g_signal_connect(G_OBJECT(application->gui->main_window), "destroy", G_CALLBACK(gui_free), application);
	g_signal_connect(GTK_SWITCH(application->gui->switch_on), "notify::active", G_CALLBACK(gui_activate), application);
	g_signal_connect(GTK_BUTTON(application->gui->toggle_go), "clicked", G_CALLBACK(gui_go), application);
}

void gui_go(GtkButton *button, Application *application) {
	pthread_t thread;
	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {	
		float ra[3] = {
			gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(application->gui->spin_ra_hours)),
			gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(application->gui->spin_ra_minutes)),
			gtk_spin_button_get_value(GTK_SPIN_BUTTON(application->gui->spin_ra_seconds))
		};
		float dec[3] = {
			gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(application->gui->spin_dec_degrees)),
			gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(application->gui->spin_dec_arcminutes)),
			gtk_spin_button_get_value(GTK_SPIN_BUTTON(application->gui->spin_dec_arcseconds))		
		};
		gui_set_sensitive_coordinate_entries(application->gui, FALSE);
		cpc800_goto_ra_dec(application->telescope, ra, dec);
		pthread_create(&thread, NULL, gui_update_coordinate_labels_text, (void *) application);
		gtk_button_set_label(GTK_BUTTON(button), CANCEL);
	}
	else {
		pthread_kill(thread, 0);
		gui_set_sensitive_coordinate_entries(application->gui, TRUE);
		gtk_button_set_label(GTK_BUTTON(button), GO);
	}	
}

void gui_init(Application *application) {
	gdk_threads_init( );
	gtk_init(&application->argc, &application->argv);
	application->gui->builder = gtk_builder_new( );
	gtk_builder_add_from_file (application->gui->builder, "convite.xml", NULL);
	gtk_builder_connect_signals(application->gui->builder, NULL);
	gui_initialize_widgets(application->gui);
	gui_connect_signals(application);
	g_object_unref(G_OBJECT(application->gui->builder));
	gtk_widget_show(application->gui->main_window);
	gtk_main( );
}

void gui_initialize_widgets(GUI *gui) {
	gui->button_pause = GTK_WIDGET(gtk_builder_get_object(gui->builder, "button1"));
	gui->button_take_photo = GTK_WIDGET(gtk_builder_get_object(gui->builder, "button2"));
	gui->entry_camera = GTK_WIDGET(gtk_builder_get_object(gui->builder, "entry6"));	
	gui->entry_telescope = GTK_WIDGET(gtk_builder_get_object(gui->builder, "entry1"));	
	gui->label_alt = GTK_WIDGET(gtk_builder_get_object(gui->builder, "label7"));	
	gui->label_azm = GTK_WIDGET(gtk_builder_get_object(gui->builder, "label9"));
	gui->label_dec_arcminutes = GTK_WIDGET(gtk_builder_get_object(gui->builder, "label21"));
	gui->label_dec_arcseconds = GTK_WIDGET(gtk_builder_get_object(gui->builder, "label22"));
	gui->label_dec_degrees = GTK_WIDGET(gtk_builder_get_object(gui->builder, "label19"));
	gui->label_dec = GTK_WIDGET(gtk_builder_get_object(gui->builder, "label5"));
	gui->label_ra = GTK_WIDGET(gtk_builder_get_object(gui->builder, "label3"));
	gui->label_ra_hours = GTK_WIDGET(gtk_builder_get_object(gui->builder, "label12"));
	gui->label_ra_minutes = GTK_WIDGET(gtk_builder_get_object(gui->builder, "label14"));
	gui->label_ra_seconds = GTK_WIDGET(gtk_builder_get_object(gui->builder, "label17"));
	gui->main_window = GTK_WIDGET(gtk_builder_get_object(gui->builder, "window1"));
	gui->spin_dec_arcminutes = GTK_WIDGET(gtk_builder_get_object(gui->builder, "spinbutton5"));
	gui->spin_dec_arcseconds = GTK_WIDGET(gtk_builder_get_object(gui->builder, "spinbutton6"));
	gui->spin_dec_degrees = GTK_WIDGET(gtk_builder_get_object(gui->builder, "spinbutton4"));
	gui->spin_ra_hours = GTK_WIDGET(gtk_builder_get_object(gui->builder, "spinbutton1"));
	gui->spin_ra_minutes = GTK_WIDGET(gtk_builder_get_object(gui->builder, "spinbutton2"));
	gui->spin_ra_seconds = GTK_WIDGET(gtk_builder_get_object(gui->builder, "spinbutton3"));
	gui->status_bar = GTK_WIDGET(gtk_builder_get_object(gui->builder, "statusbar1"));
	gui->switch_on = GTK_WIDGET(gtk_builder_get_object(gui->builder, "switch1"));
	gui->toggle_go = GTK_WIDGET(gtk_builder_get_object(gui->builder, "togglebutton1"));
	gui->toggle_record = GTK_WIDGET(gtk_builder_get_object(gui->builder, "togglebutton2"));
	gtk_button_set_label(GTK_BUTTON(gui->toggle_go), GO);	
	gtk_entry_set_placeholder_text(GTK_ENTRY(gui->entry_camera), CAMERA_PATH);
	gtk_entry_set_placeholder_text(GTK_ENTRY(gui->entry_telescope), TELESCOPE_PATH);
	gtk_entry_set_text(GTK_ENTRY(gui->entry_camera), "/dev/video0");
	gtk_entry_set_text(GTK_ENTRY(gui->entry_telescope), "/dev/ttyS0");
	gtk_label_set_text(GTK_LABEL(gui->label_dec_arcminutes), ARCMINUTES);
	gtk_label_set_text(GTK_LABEL(gui->label_dec_arcseconds), ARCSECONDS);
	gtk_label_set_text(GTK_LABEL(gui->label_dec_degrees), DEGREES);
	gtk_label_set_text(GTK_LABEL(gui->label_ra_hours), HOURS);
	gtk_label_set_text(GTK_LABEL(gui->label_ra_minutes), MINUTES);
	gtk_label_set_text(GTK_LABEL(gui->label_ra_seconds), SECONDS);
	gtk_widget_set_sensitive(gui->button_pause, FALSE);
	gtk_widget_set_sensitive(gui->button_take_photo, FALSE);
	gui_set_coordinate_labels_default_text(gui, NO_VALUE);
	gui_toggle_sensitive_widgets(gui, FALSE);
}

void gui_set_sensitive_coordinate_entries(GUI *gui, int value) {
	gtk_widget_set_sensitive(gui->spin_ra_hours, value);
	gtk_widget_set_sensitive(gui->spin_ra_minutes, value);
	gtk_widget_set_sensitive(gui->spin_ra_seconds, value);
	gtk_widget_set_sensitive(gui->spin_dec_degrees, value);
	gtk_widget_set_sensitive(gui->spin_dec_arcminutes, value);
	gtk_widget_set_sensitive(gui->spin_dec_arcseconds, value);
}

void gui_set_coordinate_labels_default_text(GUI *gui, char *value) {
	gtk_label_set_text(GTK_LABEL(gui->label_alt), value);
	gtk_label_set_text(GTK_LABEL(gui->label_azm), value);
	gtk_label_set_text(GTK_LABEL(gui->label_dec), value);
	gtk_label_set_text(GTK_LABEL(gui->label_ra), value);
}

void gui_toggle_sensitive_widgets(GUI *gui, int value) {
	gui_set_sensitive_coordinate_entries(gui, value);
	gtk_widget_set_sensitive(gui->toggle_go, value);
	gtk_widget_set_sensitive(gui->entry_telescope, !value);
	gtk_widget_set_sensitive(gui->entry_camera, !value);
}

void * gui_update_coordinate_labels_text(void *application) {
	Application *app = (Application *) application;
	while(cpc800_is_goto_in_progress(app->telescope)) {
		char dra[12], ddec[12];
		gdk_threads_enter( );
		cpc800_get_ra_dec(app->telescope, dra, ddec);
		gtk_label_set_text(GTK_LABEL(app->gui->label_ra), dra);
		gtk_label_set_text(GTK_LABEL(app->gui->label_dec), ddec);
		gdk_threads_leave( );
	}
	return NULL;
}
